Avastage Pythoni operator-mooduli vĂ”imsus, et kirjutada lĂŒhemat, tĂ”husamat ja funktsionaalsemat koodi. Tutvuge selle abifunktsioonidega levinud operatsioonide jaoks.
Pythoni operator-moodul: vÔimsad tööriistad funktsionaalseks programmeerimiseks
Programmeerimismaailmas, eriti kui omaks vĂ”tta funktsionaalse programmeerimise paradigmad, on esmatĂ€htis oskus vĂ€ljendada operatsioone puhtal, lĂŒhidal ja korduvkasutataval viisil. Kuigi Python on peamiselt objektorienteeritud keel, pakub see tugevat toetust funktsionaalse programmeerimise stiilidele. Selle toe oluline, kuigi mĂ”nikord tĂ€helepanuta jĂ€etud, komponent peitub operator
-moodulis. See moodul pakub kogumit tÔhusaid funktsioone, mis vastavad Pythoni sisemistele operaatoritele, olles suurepÀrased alternatiivid lambda-funktsioonidele ning parandades koodi loetavust ja jÔudlust.
operator
-mooduli mÔistmine
operator
-moodul defineerib funktsioonid, mis teostavad Pythoni sisseehitatud operaatoritega samavÀÀrseid operatsioone. NÀiteks operator.add(a, b)
on samavÀÀrne a + b
-ga ja operator.lt(a, b)
on samavÀÀrne a < b
-ga. Need funktsioonid on sageli tÔhusamad kui nende operaatoritest vasted, eriti jÔudluskriitilistes kontekstides, ja neil on oluline roll funktsionaalse programmeerimise konstruktsioonides nagu map()
, filter()
ja functools.reduce()
.
Miks peaksite kasutama operator
-mooduli funktsiooni otse operaatori asemel? Peamised pÔhjused on:
- Ăhilduvus funktsionaalse stiiliga: Paljud kĂ”rgemat jĂ€rku funktsioonid Pythonis (nagu need
functools
-moodulis) ootavad kutsutavaid objekte. Operaatorfunktsioonid on kutsutavad, mis teeb neist ideaalsed argumendid, mida edasi anda ilma eraldi lambda-funktsiooni defineerimata. - Loetavus: Teatud keerulistes olukordades vÔib nimetatud operaatorfunktsioonide kasutamine mÔnikord parandada koodi selgust vÔrreldes keerukate lambda-avaldistega.
- JĂ”udlus: Teatud operatsioonide puhul, eriti kui neid kutsutakse korduvalt tsĂŒklites vĂ”i kĂ”rgemat jĂ€rku funktsioonides, vĂ”ivad operaatorfunktsioonid pakkuda kerget jĂ”udluse eelist tĂ€nu nende C-keeles implementeerimisele.
PÔhilised operaatorfunktsioonid
operator
-mooduli vĂ”ib laias laastus liigitada nende esindatavate operatsioonide tĂŒĂŒpide jĂ€rgi. Uurime mĂ”ningaid kĂ”ige sagedamini kasutatavaid.
Aritmeetilised operaatorid
Need funktsioonid teostavad standardseid aritmeetilisi arvutusi. Need on eriti kasulikud, kui peate edastama aritmeetilise operatsiooni argumendina teisele funktsioonile.
operator.add(a, b)
: SamavÀÀrnea + b
-ga.operator.sub(a, b)
: SamavÀÀrnea - b
-ga.operator.mul(a, b)
: SamavÀÀrnea * b
-ga.operator.truediv(a, b)
: SamavÀÀrnea / b
-ga (tÔene jagamine).operator.floordiv(a, b)
: SamavÀÀrnea // b
-ga (tÀisarvuline jagamine).operator.mod(a, b)
: SamavÀÀrnea % b
-ga (jÀÀk).operator.pow(a, b)
: SamavÀÀrnea ** b
-ga (astendamine).operator.neg(a)
: SamavÀÀrne-a
-ga (unaarne negatsioon).operator.pos(a)
: SamavÀÀrne+a
-ga (unaarne positiivne).operator.abs(a)
: SamavÀÀrneabs(a)
-ga.
NĂ€ide: operator.add
kasutamine koos functools.reduce
-ga
Kujutage ette, et peate summeerima kÔik elemendid nimekirjas. Kuigi sum()
on kÔige pythonilikum viis, demonstreerib reduce
kasutamine koos operaatorfunktsiooniga selle kasulikkust:
import operator
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# Kasutades reduce koos operator.add-ga
total = reduce(operator.add, numbers)
print(f"Summa {numbers} on: {total}") # VĂ€ljund: Summa [1, 2, 3, 4, 5] on: 15
See on funktsionaalselt samavÀÀrne jÀrgnevaga:
total_lambda = reduce(lambda x, y: x + y, numbers)
print(f"Summa lambda abil: {total_lambda}") # VĂ€ljund: Summa lambda abil: 15
operator.add
versiooni eelistatakse sageli selle selguse ja potentsiaalsete jÔudluseeliste tÔttu.
VÔrdlusoperaatorid
Need funktsioonid teostavad vÔrdlusi kahe operandi vahel.
operator.lt(a, b)
: SamavÀÀrnea < b
-ga (vÀiksem kui).operator.le(a, b)
: SamavÀÀrnea <= b
-ga (vÀiksem vÔi vÔrdne).operator.eq(a, b)
: SamavÀÀrnea == b
-ga (vÔrdne).operator.ne(a, b)
: SamavÀÀrnea != b
-ga (mitte vÔrdne).operator.ge(a, b)
: SamavÀÀrnea >= b
-ga (suurem vÔi vÔrdne).operator.gt(a, b)
: SamavÀÀrnea > b
-ga (suurem kui).
NÀide: SÔnastike nimekirja sorteerimine konkreetse vÔtme jÀrgi
Oletame, et teil on nimekiri kasutajaprofiilidest, millest igaĂŒks on esitatud sĂ”nastikuna, ja soovite neid sorteerida nende 'score' (skoori) jĂ€rgi.
import operator
users = [
{'name': 'Alice', 'score': 85},
{'name': 'Bob', 'score': 92},
{'name': 'Charlie', 'score': 78}
]
# Sorteeri kasutajad skoori jÀrgi kasutades operator.itemgetter
sorted_users = sorted(users, key=operator.itemgetter('score'))
print("Kasutajad sorteeritud skoori jÀrgi:")
for user in sorted_users:
print(user)
# VĂ€ljund:
# Kasutajad sorteeritud skoori jÀrgi:
# {'name': 'Charlie', 'score': 78}
# {'name': 'Alice', 'score': 85}
# {'name': 'Bob', 'score': 92}
Siin on operator.itemgetter('score')
kutsutav, mis sÔnastiku saamisel tagastab vÀÀrtuse, mis on seotud vÔtmega 'score'. See on puhtam ja tÔhusam kui kirjutada key=lambda user: user['score']
.
Loogikatehted
Need funktsioonid teostavad loogilisi operatsioone.
operator.not_(a)
: SamavÀÀrnenot a
-ga.operator.truth(a)
: TagastabTrue
, kuia
on tÔene, vastasel juhulFalse
.operator.is_(a, b)
: SamavÀÀrnea is b
-ga.operator.is_not(a, b)
: SamavÀÀrnea is not b
-ga.
NÀide: VÀÀrate (falsy) vÀÀrtuste vÀljafiltreerimine
Saate kasutada operator.truth
koos filter()
-iga, et eemaldada kÔik vÀÀrad vÀÀrtused (nagu 0
, None
, tĂŒhjad stringid, tĂŒhjad nimekirjad) itereeritavast objektist.
import operator
data = [1, 0, 'hello', '', None, [1, 2], []]
# Filtreeri vÀlja vÀÀrad vÀÀrtused kasutades operator.truth
filtered_data = list(filter(operator.truth, data))
print(f"Algandmed: {data}")
print(f"Filtreeritud andmed (tÔesed vÀÀrtused): {filtered_data}")
# VĂ€ljund:
# Algandmed: [1, 0, 'hello', '', None, [1, 2], []]
# Filtreeritud andmed (tÔesed vÀÀrtused): [1, 'hello', [1, 2]]
Bitikaupa operaatorid
Need funktsioonid opereerivad tĂ€isarvude ĂŒksikutel bittidel.
operator.and_(a, b)
: SamavÀÀrnea & b
-ga.operator.or_(a, b)
: SamavÀÀrnea | b
-ga.operator.xor(a, b)
: SamavÀÀrnea ^ b
-ga.operator.lshift(a, b)
: SamavÀÀrnea << b
-ga.operator.rshift(a, b)
: SamavÀÀrnea >> b
-ga.operator.invert(a)
: SamavÀÀrne~a
-ga.
NĂ€ide: Bitikaupa operatsioonide teostamine
import operator
a = 10 # Binaarne: 1010
b = 4 # Binaarne: 0100
print(f"a & b: {operator.and_(a, b)}") # VĂ€ljund: a & b: 0 (Binaarne: 0000)
print(f"a | b: {operator.or_(a, b)}") # VĂ€ljund: a | b: 14 (Binaarne: 1110)
print(f"a ^ b: {operator.xor(a, b)}") # VĂ€ljund: a ^ b: 14 (Binaarne: 1110)
print(f"~a: {operator.invert(a)}") # VĂ€ljund: ~a: -11
JĂ€rjendi ja vastenduse operaatorid
Need funktsioonid on kasulikud elementidele ligipÀÀsemiseks jÀrjendites (nagu nimekirjad, ennikud, stringid) ja vastendustes (nagu sÔnastikud).
operator.getitem(obj, key)
: SamavÀÀrneobj[key]
-ga.operator.setitem(obj, key, value)
: SamavÀÀrneobj[key] = value
-ga.operator.delitem(obj, key)
: SamavÀÀrnedel obj[key]
-ga.operator.len(obj)
: SamavÀÀrnelen(obj)
-ga.operator.concat(a, b)
: SamavÀÀrnea + b
-ga (jÀrjendite, nagu stringid vÔi nimekirjad, puhul).operator.contains(obj, item)
: SamavÀÀrneitem in obj
-ga.
operator.itemgetter
: vÔimas tööriist
Nagu sorteerimisnÀites vihjatud, on operator.itemgetter
spetsialiseeritud funktsioon, mis on uskumatult kasulik. Kui seda kutsutakse ĂŒhe vĂ”i mitme argumendiga, tagastab see kutsutava, mis hangib need elemendid oma operandist. Kui antakse mitu argumenti, tagastab see hangitud elementide enniku.
import operator
# Ăhe elemendi hankimine
get_first_element = operator.itemgetter(0)
my_list = [10, 20, 30]
print(f"Esimene element: {get_first_element(my_list)}") # VĂ€ljund: Esimene element: 10
# Mitme elemendi hankimine
get_first_two = operator.itemgetter(0, 1)
print(f"Esimesed kaks elementi: {get_first_two(my_list)}") # VĂ€ljund: Esimesed kaks elementi: (10, 20)
# Elementide hankimine sÔnastikust
get_name_and_score = operator.itemgetter('name', 'score')
user_data = {'name': 'Alice', 'score': 85, 'city': 'New York'}
print(f"Kasutaja info: {get_name_and_score(user_data)}") # VĂ€ljund: Kasutaja info: ('Alice', 85)
operator.itemgetter
on ka vÀga tÔhus, kui seda kasutatakse key
-argumendina sorteerimisel vÔi teistes funktsioonides, mis aktsepteerivad vÔtmefunktsiooni.
operator.attrgetter
: atribuutidele ligipÀÀsemine
Sarnaselt itemgetter
-ile tagastab operator.attrgetter
kutsutava, mis hangib atribuudid oma operandist. See on eriti kÀepÀrane objektidega töötamisel.
import operator
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
products = [
Product('Laptop', 1200),
Product('Mouse', 25),
Product('Keyboard', 75)
]
# Hangi kÔik tootenimed
get_name = operator.attrgetter('name')
product_names = [get_name(p) for p in products]
print(f"Tootenimed: {product_names}") # VĂ€ljund: Tootenimed: ['Laptop', 'Mouse', 'Keyboard']
# Sorteeri tooted hinna jÀrgi
sorted_products = sorted(products, key=operator.attrgetter('price'))
print("Tooted sorteeritud hinna jÀrgi:")
for p in sorted_products:
print(f"- {p.name}: ${p.price}")
# VĂ€ljund:
# Tooted sorteeritud hinna jÀrgi:
# - Mouse: $25
# - Keyboard: $75
# - Laptop: $1200
attrgetter
pÀÀseb ligi ka atribuutidele lÀbi pesastatud objektide, kasutades punktnotatsiooni. NÀiteks operator.attrgetter('address.city')
hangiks 'city' atribuudi objekti 'address' atribuudist.
Muud kasulikud funktsioonid
operator.methodcaller(name, *args, **kwargs)
: Tagastab kutsutava, mis kutsub oma operandil vÀlja meetodi nimeganame
. See on meetodite vasteitemgetter
-ile jaattrgetter
-ile.
NÀide: meetodi vÀljakutsumine nimekirjas olevatel objektidel
import operator
class Greeter:
def __init__(self, name):
self.name = name
def greet(self, message):
return f"{self.name} ĂŒtleb: {message}"
greeters = [Greeter('Alice'), Greeter('Bob')]
# Kutsu greet-meetod vÀlja igal Greeter-objektil
call_greet = operator.methodcaller('greet', 'Tervitused operator-moodulist!')
greetings = [call_greet(g) for g in greeters]
print(greetings)
# VĂ€ljund: ['Alice ĂŒtleb: Tervitused operator-moodulist!', 'Bob ĂŒtleb: Tervitused operator-moodulist!']
operator
-moodul funktsionaalse programmeerimise kontekstis
operator
-mooduli tÔeline jÔud avaldub, kui seda kasutatakse koos Pythoni sisseehitatud funktsionaalse programmeerimise tööriistadega nagu map()
, filter()
ja functools.reduce()
.
map()
ja operator
map(function, iterable, ...)` rakendab funktsiooni igale itereeritava elemendile ja tagastab tulemuste iteraatori. Operaatorfunktsioonid sobivad selleks ideaalselt.
import operator
numbers = [1, 2, 3, 4, 5]
# Ruuduta iga arv kasutades map-i ja operator.mul-i
squared_numbers = list(map(lambda x: operator.mul(x, x), numbers)) # VÔib olla lihtsam: list(map(operator.mul, numbers, numbers)) vÔi list(map(pow, numbers, [2]*len(numbers)))
print(f"Ruudutatud arvud: {squared_numbers}") # VĂ€ljund: Ruudutatud arvud: [1, 4, 9, 16, 25]
# Liida igale arvule 10 kasutades map-i ja operator.add-i
added_ten = list(map(operator.add, numbers, [10]*len(numbers)))
print(f"Arvud pluss 10: {added_ten}") # VĂ€ljund: Arvud pluss 10: [11, 12, 13, 14, 15]
filter()
ja operator
filter(function, iterable)` konstrueerib iteraatori itereeritava elementidest, mille puhul funktsioon tagastab tÔese vÀÀrtuse. Oleme nÀinud
operator.truth
-i, kuid ka teised vÔrdlusoperaatorid on vÀga kasulikud.
import operator
salaries = [50000, 65000, 45000, 80000, 70000]
# Filtreeri palgad, mis on suuremad kui 60000
high_salaries = list(filter(operator.gt, salaries, [60000]*len(salaries)))
print(f"Palgad ĂŒle 60000: {high_salaries}") # VĂ€ljund: Palgad ĂŒle 60000: [65000, 80000, 70000]
# Filtreeri paarisarvud kasutades operator.mod ja lambda (vÔi keerulisemat operaatorfunktsiooni)
even_numbers = list(filter(lambda x: operator.eq(operator.mod(x, 2), 0), [1, 2, 3, 4, 5, 6]))
print(f"Paarisarvud: {even_numbers}") # VĂ€ljund: Paarisarvud: [2, 4, 6]
functools.reduce()
ja operator
functools.reduce(function, iterable[, initializer])` rakendab kahe argumendiga funktsiooni kumulatiivselt itereeritava elementidele, vasakult paremale, et taandada itereeritav ĂŒhele vÀÀrtusele. Operaatorfunktsioonid on ideaalsed binaarsete operatsioonide jaoks.
import operator
from functools import reduce
numbers = [2, 3, 4, 5]
# Arvuta arvude korrutis
product = reduce(operator.mul, numbers)
print(f"Korrutis: {product}") # VĂ€ljund: Korrutis: 120
# Leia maksimaalne arv
maximum = reduce(operator.gt, numbers)
print(f"Maksimum: {maximum}") # See ei tööta max-i jaoks ootuspÀraselt, vaja on kasutada lambdat vÔi kohandatud funktsiooni max-i jaoks:
# Kasutades lambdat max-i jaoks:
maximum_lambda = reduce(lambda x, y: x if x > y else y, numbers)
print(f"Maksimum (lambda): {maximum_lambda}") # VĂ€ljund: Maksimum (lambda): 5
# MĂ€rkus: Maksimumi leidmiseks eelistatakse ĂŒldiselt sisseehitatud funktsiooni max().
JÔudlusega seotud kaalutlused
Kuigi jĂ”udluserinevused vĂ”ivad paljudes igapĂ€evastes skriptides olla tĂŒhised, on operator
-mooduli funktsioonid implementeeritud C-keeles ja vĂ”ivad pakkuda kiiruseelist samavÀÀrse Pythoni koodi (eriti lambda-funktsioonide) ees, kui neid kasutatakse tihedates tsĂŒklites vĂ”i vĂ€ga suurte andmekogumite töötlemisel. Seda seetĂ”ttu, et nad vĂ€ldivad Pythoni funktsioonikutse mehhanismiga seotud lisakulusid.
NĂ€iteks, kui kasutada operator.itemgetter
-it vÔi operator.attrgetter
-it vĂ”tmetena sorteerimisel, on nad ĂŒldiselt kiiremad kui samavÀÀrsed lambda-funktsioonid. Samamoodi vĂ”ivad aritmeetiliste operatsioonide puhul map
-i vÔi reduce
-i sees operaatorfunktsioonid anda kerge tÔuke.
Millal kasutada operator
-mooduli funktsioone
Siin on lĂŒhike juhend, millal haarata operator
-mooduli jÀrele:
- KÔrgemat jÀrku funktsioonide argumentidena: Funktsioonide edastamisel
map
-ile,filter
-ile,sorted
-ile,functools.reduce
-ile vÔi sarnastele konstruktsioonidele. - Kui loetavus paraneb: Kui operaatorfunktsioon muudab teie koodi selgemaks kui lambda, kasutage seda.
- JÔudluskriitilise koodi jaoks: Kui profileerite oma koodi ja leiate, et operaatorikutsed on kitsaskohaks, vÔivad mooduli funktsioonid aidata.
- Elementidele/atribuutidele ligipÀÀsemiseks:
operator.itemgetter
-it jaoperator.attrgetter
-it eelistatakse peaaegu alati lambdadele sel eesmÀrgil nende selguse ja tÔhususe tÔttu.
Levinud lÔksud ja parimad praktikad
- Ărge kasutage seda ĂŒle: Kui lihtne operaator nagu
+
vÔi*
on kontekstis piisavalt selge, jÀÀge selle juurde.operator
-moodul on mÔeldud funktsionaalse programmeerimise stiilide tÀiustamiseks vÔi siis, kui on vaja selgesÔnalisi funktsiooniargumente. - MÔistke tagastusvÀÀrtusi: Pidage meeles, et funktsioonid nagu
map
jafilter
tagastavad iteraatoreid. Kui vajate nimekirja, teisendage tulemus selgesÔnaliselt kasutadeslist()
-i. - Kombineerige teiste tööriistadega:
operator
-moodul on kÔige vÔimsam, kui seda kasutatakse koos teiste Pythoni konstruktsioonide ja moodulitega, eritifunctools
-iga. - Loetavus ennekÔike: Kuigi jÔudlus on oluline tegur, eelistage selget ja hooldatavat koodi. Kui lambda on konkreetse, lihtsa juhtumi puhul koheselt arusaadavam, vÔib see olla vastuvÔetav.
KokkuvÔte
Pythoni operator
-moodul on vÀÀrtuslik, ehkki mÔnikord alahinnatud, tööriist iga Pythoni programmeerija arsenalis, eriti neile, kes kalduvad funktsionaalse programmeerimise poole. Pakkudes otseseid, tÔhusaid ja kutsutavaid vasteid Pythoni operaatoritele, muudab see elegantse ja jÔudsa koodi loomise sujuvamaks. Olenemata sellest, kas sorteerite keerulisi andmestruktuure, teostate koondoperatsioone vÔi rakendate teisendusi, vÔib operator
-mooduli funktsioonide vĂ”imendamine viia lĂŒhemate, loetavamate ja optimeeritud Pythoni programmideni. VĂ”tke need tööriistad omaks, et oma Pythoni kodeerimispraktikaid tĂ€iustada.